﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data;

namespace DataAccess
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
    public sealed class DataColumnAttribute : Attribute
    {
        private const BindingFlags Flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy;

        private string _name = null;

        public string Name
        {
            get
            {
                return _name;
            }

        }

        public DataColumnAttribute()
        {

        }

        public DataColumnAttribute(string name)
        {
            _name = name;
        }

        private string GetName(MemberInfo member)
        {
            return _name ?? member.Name;
        }

        public static void Bind(DataRow row, DataColumnCollection columns,  object target)
        {
            Type type = target.GetType();

            foreach (DataColumn column in columns)
            {

                foreach (FieldInfo field in type.GetFields(Flags))
                {

                    foreach (DataColumnAttribute att in field.GetCustomAttributes(typeof(DataColumnAttribute), true))
                    {

                        att.Bind(column.ColumnName, target, field, row[column]);

                    }
                }

                foreach (PropertyInfo property in type.GetProperties(Flags))
                {
                    foreach (DataColumnAttribute att in type.GetCustomAttributes(typeof(DataColumnAttribute), true))
                    {

                        att.Bind(column.ColumnName, target, property, row[column]);

                    }
                }
            }
        }


        private void Bind(string columnName, object target, FieldInfo field, object value)
        {

            if (GetName(field) == columnName)
            {

                field.SetValue(target, value);

            }

        }

        private void Bind(string columnName, object target, PropertyInfo property, object value)
        {

            if (GetName(property) == columnName)
            {

                property.SetValue(target, value, null);

            }

        }
    }
}
